package com.cs.mybatis.configurer;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.StringUtils;

import com.alibaba.druid.pool.DruidDataSource;
import com.cs.mybatis.utils.MybaitsPropertyUtil2;

@Configuration
public class MyBeanDefinitionRegistryMybatis implements BeanDefinitionRegistryPostProcessor {

	private static final Logger logger = LoggerFactory.getLogger(MyBeanDefinitionRegistryMybatis.class);

	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
	}

	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException{
		logger.info("Invoke Metho MyBeanDefinitionRegistryMybatis postProcessBeanDefinitionRegistry");
		
		MybaitsPropertyUtil2 redisPropertyUtil = new MybaitsPropertyUtil2("application.properties");
        
        String nameList = redisPropertyUtil.getProperty("csboot.mybatis.name");
        if(!StringUtils.isEmpty(nameList))
    	{
        	String[] namesplit = nameList.split(",");
            for(String name : namesplit)
            {
            	if(StringUtils.isEmpty(name))
            	{
            		continue;
            	}
            	registerBean(registry, name);
            }
    		
    	}
	}
	
	 private void registerBean(BeanDefinitionRegistry registry, String name){
			 MybaitsPropertyUtil2 mybaitsPropertyUtil2 = new MybaitsPropertyUtil2(name+".properties");
			 String dasourceNname = mybaitsPropertyUtil2.getProperty("datasource.name");
			 
			 String driverClassName = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".driverClassName");
			 String url = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".url");
			 String userName = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".userName");
			 String passWord = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".passWord");
			 
			 //datasource
			 BeanDefinitionBuilder builderDruidDataSource = BeanDefinitionBuilder.genericBeanDefinition(DruidDataSource.class);
			 builderDruidDataSource.addPropertyValue("driverClassName", driverClassName);
			 builderDruidDataSource.addPropertyValue("url", url);
			 builderDruidDataSource.addPropertyValue("username", userName);
			 builderDruidDataSource.addPropertyValue("password", passWord);
			 builderDruidDataSource.addPropertyValue("name", dasourceNname+"DruidDataSource");
		     registry.registerBeanDefinition(dasourceNname+"DruidDataSource", builderDruidDataSource.getBeanDefinition());
		     
		     //sqlSessionFactoryBean
		    String modelPackage = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".modelPackage");
			String XmlPackage = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".XmlPackage");
			ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
			Resource[] resource = null;
			try {
			       resource= resolver.getResources("classpath:" + XmlPackage + "/*.xml");
			}
			catch(Exception ex)
			{
				logger.error(ex.toString());;
			}
				
			 BeanDefinitionBuilder builderSqlSessionFactory = BeanDefinitionBuilder.genericBeanDefinition(SqlSessionFactoryBean.class);
			 builderSqlSessionFactory.addPropertyReference("dataSource", dasourceNname+"DruidDataSource");
			 builderSqlSessionFactory.addPropertyValue("typeAliasesPackage", modelPackage);
			 builderSqlSessionFactory.addPropertyValue("mapperLocations", resource);
		     registry.registerBeanDefinition(dasourceNname+"SqlSessionFactory", builderSqlSessionFactory.getBeanDefinition());
		     
		   //SqlSessionTemplate
		     BeanDefinitionBuilder builderSqlSessionTemplate = BeanDefinitionBuilder.genericBeanDefinition(SqlSessionTemplate.class);
		     builderSqlSessionTemplate.addConstructorArgReference(dasourceNname+"SqlSessionFactory");
			 registry.registerBeanDefinition(dasourceNname+"SqlSessionTemplate", builderSqlSessionTemplate.getBeanDefinition());
		     
		     //MapperScannerConfigurer
		     String mapperPackage = mybaitsPropertyUtil2.getProperty("datasource."+dasourceNname+".mapperPackage");
		     
		     BeanDefinitionBuilder builderMapperScannerConfigurer = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
		     builderMapperScannerConfigurer.addPropertyValue("sqlSessionFactoryBeanName", dasourceNname+"SqlSessionFactory");
		     builderMapperScannerConfigurer.addPropertyValue("sqlSessionTemplateBeanName", dasourceNname+"SqlSessionTemplate");
		     builderMapperScannerConfigurer.addPropertyValue("basePackage", mapperPackage);
		     builderMapperScannerConfigurer.addPropertyValue("beanName", dasourceNname+"MapperScannerConfigurer");
		     registry.registerBeanDefinition(dasourceNname+"MapperScannerConfigurer", builderMapperScannerConfigurer.getBeanDefinition());
		     
		     //DataSourceTransactionManager
		     BeanDefinitionBuilder builderDataSourceTransactionManager = BeanDefinitionBuilder.genericBeanDefinition(DataSourceTransactionManager.class);
		     builderDataSourceTransactionManager.addConstructorArgReference(dasourceNname+"DruidDataSource");
		     registry.registerBeanDefinition(dasourceNname+"DataSourceTransactionManager", builderDataSourceTransactionManager.getBeanDefinition()); 
	    }
}
